<template>
    <van-uploader :fileList="$attrs.value" :before-read="beforeReadFn" v-bind="$attrs" v-on="$listeners">
        <slot></slot>
    </van-uploader>
</template>
<script lang="js">
export default {
    name: 'van-small-upload',
    props: {
        quality:{
            type:Number,
            default:0.1
        },
        compressSwitch:{
            type:Boolean,
            default:false
        },
        threshold:{
            type:Number,
            default:500
        },
        beforeRead:{
            type: Function,
            default:()=>true
        }
    },
    data() {
        return {

        }
    },
    methods: {
        // 处理图片
        imgPreview(file,index) {
            let self = this
            // 看支持不支持FileReader
            if (!file || !window.FileReader) return;
            const size = file.size/1024
            if (/^image/.test(file.type) && size >= this.threshold && this.compressSwitch) {
                // 创建一个reader
                let reader = new FileReader()
                // 将图片2将转成 base64 格式
                reader.readAsDataURL(file)
                // 读取成功后的回调
                reader.onloadend = function() {
                    let result = this.result
                    let img = new Image()
                    img.src = result
                    img.onload = function() {
                        // 压缩
                        let data = self.compress(img,file.name,file.type)
                        console.log(`压缩后 ===>${data.fileData.size/1024}k`);
                        self.$attrs.value[index].content = data.base64Data
                        self.$attrs.value[index].file = data.fileData
                    }
                }
            }
        },
        // 压缩图片
        compress(img, name, type) {
            let canvas = document.createElement('canvas')
            let ctx = canvas.getContext('2d')
            //瓦片canvas
            let tCanvas = document.createElement('canvas')
            let tctx = tCanvas.getContext('2d')
            // let initSize = img.src.length;
            let width = img.width
            let height = img.height
            //如果图片大于四百万像素，计算压缩比并将大小压至400万以下
            let ratio
            if ((ratio = (width * height) / 4000000) > 1) {
                // console.log("大于400万像素");
                ratio = Math.sqrt(ratio)
                width /= ratio
                height /= ratio
            } else {
                ratio = 1
            }
            canvas.width = width
            canvas.height = height
            //    铺底色
            ctx.fillStyle = '#fff'
            ctx.fillRect(0, 0, canvas.width, canvas.height)
            //如果图片像素大于100万则使用瓦片绘制
            let count
            if ((count = (width * height) / 1000000) > 1) {
                // console.log("超过100W像素");
                count = ~~(Math.sqrt(count) + 1) //计算要分成多少块瓦片
                //      计算每块瓦片的宽和高
                let nw = ~~(width / count)
                let nh = ~~(height / count)
                tCanvas.width = nw
                tCanvas.height = nh
                for (let i = 0; i < count; i++) {
                    for (let j = 0; j < count; j++) {
                        tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh)
                        ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh)
                    }
                }
            } else {
                ctx.drawImage(img, 0, 0, width, height)
            }
            //进行压缩
            let ndata = canvas.toDataURL('image/jpeg', this.quality)
            tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
            return {base64Data:ndata,fileData:this.dataURLtoFile(ndata,name,type)}
        },
        //将base64转换为文件
        dataURLtoFile(dataurl,name,type) {
            name = name ? name : '图片'
            type = type ? type : 'jpg'
            var arr = dataurl.split(','),
                bstr = atob(arr[1]),
                n = bstr.length,
                u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            return new File([u8arr], name, {
                type: type
            })
        },
        beforeReadFn(file,detail){
            const {index} = detail
            this.imgPreview(file,index)
            return this.beforeRead(...arguments);
        }
    },
    mounted(){

    }
};
</script>
